package oop.ex3.nameserver;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.concurrent.ExecutorService;

import oop.ex3.messages.ValidHeaders;

import oop.ex3.nameserver.actions.*;
import oop.ex3.sockets.ClientSocket;

public class Listener implements Runnable {
	
	private static final int TIMEOUT = 5000;

	protected static volatile Boolean _listening = true;
		
	private static ServerSocket _myServer;
	private static HashMap<String, NsAction> _actions;
	private static NSContext _context;
	private ExecutorService _executor;
	
	/**
	 * constructor for listener
	 * @param port - port to listen to
	 * @param context - NS data 
	 * @throws IOException
	 */
	public Listener(int port, NSContext context, ExecutorService executor) 
	throws IOException{
		_myServer = new ServerSocket(port);
//		_myServer.setSoTimeout(TIMEOUT);
		_context = context;
		createActionsList();
		_executor = executor;
	}
	
	/**
	 * creates actions list
	 */
	private void createActionsList(){
	
		_actions = new HashMap<String, NsAction>();
		
		AddFile addFile = new AddFile(_context);
		AddServer addServer = new AddServer(_context);
		ClearFiles clearFiles = new ClearFiles(_context);
		DeleteFile deleteFile = new DeleteFile(_context);
		SearchFile searchFile = new SearchFile(_context);
		SendFiles sendFiles = new SendFiles(_context);
		SendServers sendServers = new SendServers(_context);
		
		_actions.put(ValidHeaders.CONTAINFILE, addFile);
		_actions.put(ValidHeaders.GOODBYE, clearFiles);
		_actions.put(ValidHeaders.DONTCONTAINFILE, deleteFile);
		_actions.put(ValidHeaders.WANTFILE, searchFile);
		_actions.put(ValidHeaders.WANTALLFILES, sendFiles);
		_actions.put(ValidHeaders.WANTSERVERS, sendServers);
		_actions.put(ValidHeaders.CONTAINNAMESERVER, addServer);
		
	}
	

	@Override
	public void run() {
		
		while(_listening){
			try {
				_executor.execute(new SessionHandler(_myServer.accept(),
						_actions, _context));
			} catch (UnknownHostException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
	}

}
